package org.jeecg.modules.network.network.tcp;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * tcp服务初始化程序
 * @author zhouwenrong
 */
@Slf4j
@NoArgsConstructor
public class TcpServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    private EventExecutorGroup group;
    private Long readerIdleTime;
    private Long writeIdleTime;

    public TcpServerChannelInitializer(int nThreads) {
        group = new DefaultEventExecutorGroup(nThreads);
    }

    public TcpServerChannelInitializer(int nThreads, long readerIdleTime, long writeIdleTime) {
        this(nThreads);
        this.writeIdleTime = writeIdleTime;
        this.readerIdleTime = readerIdleTime;
    }

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {

        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast(group, new TcpServerConnectHandler());

        //IdleStateHandler心跳机制,如果超时触发Handle中userEventTrigger()方法
        pipeline.addLast("logging", new LoggingHandler(LogLevel.INFO));
        pipeline.addLast("idleStateHandler", new IdleStateHandler(readerIdleTime, writeIdleTime, 0, TimeUnit.MINUTES));

        // netty基于分割符的自带解码器，根据提供的分隔符解析报文，这里是0x7e;1024表示单条消息的最大长度，解码器在查找分隔符的时候，达到该长度还没找到的话会抛异常
        pipeline.addLast(new DelimiterBasedFrameDecoder(1024, Unpooled.copiedBuffer(new byte[] { 0x7e })));

        pipeline.addLast(group, new TcpServerReceiveHandler());
    }
}
